/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package praticav.dao;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import praticav.model.Producao;
import praticav.util.HibernateUtil;
import java.util.List;
import javax.swing.JOptionPane;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import praticav.model.AtividadesPlanejadas;
import praticav.model.Fases;

/**
 * @author Katiane
 */
public class ProducaoDAO {
    public ProducaoDAO() {
  sessao = HibernateUtil.getsession();
  }
    
  private Session sessao;
  private int qtde;
  GregorianCalendar vetor[] = new GregorianCalendar[1000];
  
  public void inserir(Producao c) {
    Transaction t = sessao.beginTransaction();
    sessao.save(c);
    t.commit();
  }
  
  public void editar(Producao c) {
    Transaction t = sessao.beginTransaction();
    sessao.merge(c);
    t.commit();    
  }
  
  public void excluir(Producao c) {
    Transaction t = sessao.beginTransaction();
    sessao.delete(c);
    t.commit();
  }
  
  public List<Producao> listar() {
    Query qu = sessao.createQuery("from Producao"); 
    return qu.list();
  }
    
  public Producao buscar(int codigo){
    return (Producao) sessao.load(Producao.class, codigo);
  }   
  
  public void calculaInicio(Producao p, int Sequencial, GregorianCalendar inicialP) throws ParseException {
  
      
    calcula(p, Sequencial, inicialP);
    

    GregorianCalendar dtaFinal = new GregorianCalendar();
    GregorianCalendar dtaUltimaData = new GregorianCalendar();
    //JOptionPane.showMessageDialog(null, "p.getProdtafim(): "+p.getProdtafim()+"\n p.getProcodigo()"+p.getProcodigo());    
    dtaFinal.setTime(p.getProdtafim());
    //JOptionPane.showMessageDialog(null, "DtaFinal: "+dtaFinal.getTime());
    dtaUltimaData.set(2000,01,01);
    
    
    //Agora altera para a data final da produção
    FasesDAO daoFase = new FasesDAO();  
    for (Fases f : daoFase.listar(p.getProcodigo(), 0, "", "", "", "", "")) { 
        //JOptionPane.showMessageDialog(null, "Fase: "+f.getFasdescricao());
        AtividadesPlanejadasDAO daoAT = new AtividadesPlanejadasDAO();
        GregorianCalendar dta = new GregorianCalendar();
        dta.setTime(f.getFasdtafinal());
        if (dtaUltimaData.before(dta)== true){
            dtaUltimaData.setTime(dta.getTime());
        }
        //modeloFase.addRow(new String[] {""+ f.getFassequencial(), ""+ f.getFasdescricao(), "", "" + f.getFaspredecessor(), "" + f.getFasdtainicial(), ""+f.getFasdtafinal()});            
        //navega nas atividades das fases
        for (AtividadesPlanejadas at : daoAT.listar(p.getProcodigo(), f.getChave().getFascodigo(), 0, "", "", "", "", "")) { 
            //modeloFase.addRow(new String[] {""+ at.getAtiplansequencial(), "", ""+at.getAtiplandescricao(), "" + at.getAtiplanpredecessor(), ""+at.getAtiplandtainicial(), ""+at.getAtiplandtafinal(),""+at.getAtiplanintervaloantes(), ""+at.getAtiplanleadtime(),""+at.getAtiplanintervalodepois()});            
            dta.setTime(at.getAtiplandtafinal());
            if (dtaUltimaData.before(dta)== true){
                dtaUltimaData.setTime(dta.getTime());
            }
        }         
    }
    //JOptionPane.showMessageDialog(null, "Ultima Data Encontrada: "+dtaUltimaData.getTime()+"Dt Final: "+dtaFinal.getTime());
    //int diferenca = dtaFinal.compareTo(dtaUltimaData);
    long diferencaLong = dtaFinal.getTimeInMillis() - dtaUltimaData.getTimeInMillis();
    int diferenca = (int) (diferencaLong/(24*60*60*1000));
    //JOptionPane.showMessageDialog(null, "diferenca: "+diferenca);
    
    
    if (diferenca > 0){//navega adicionando mais dias nas datas pois o término já calculado foi anterior ao que deveria ser
        for (Fases f : daoFase.listar(1, 0, "", "", "", "", "")) { 

            AtividadesPlanejadasDAO daoAT = new AtividadesPlanejadasDAO();
            GregorianCalendar dtaIni = new GregorianCalendar();
            GregorianCalendar dtaFim = new GregorianCalendar();

            dtaIni.setTime(f.getFasdtainicial());
            dtaIni.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

            dtaFim.setTime(f.getFasdtafinal());
            dtaFim.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

            SimpleDateFormat formatarDate = new SimpleDateFormat("dd/MM/yyyy");   
            String DataStrIni = formatarDate.format(dtaIni.getTime());
            String DataStrFim = formatarDate.format(dtaFim.getTime());

            try {
                f.setFasdtainicial(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrIni));
                f.setFasdtafinal(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrFim));
            } catch (ParseException e) {
                JOptionPane.showMessageDialog(null, "Data incorreta!");
            }
            //System.out.println("Fase: "+f.getChave().getFascodigo() + " - "+f.getFasdescricao());
            FasesDAO daoFaseAtualiza = new FasesDAO();
            daoFaseAtualiza.editar(f);

            //navega nas atividades das fases
            for (AtividadesPlanejadas at : daoAT.listar(1, f.getChave().getFascodigo(), 0, "", "", "", "", "")) { 
                dtaIni.setTime(at.getAtiplandtainicial());
                dtaIni.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

                dtaFim.setTime(at.getAtiplandtafinal());
                dtaFim.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

                DataStrIni = formatarDate.format(dtaIni.getTime());
                DataStrFim = formatarDate.format(dtaFim.getTime());

                try {
                    at.setAtiplandtainicial(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrIni));
                    at.setAtiplandtafinal(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrFim));
                } catch (ParseException e) {
                    JOptionPane.showMessageDialog(null, "Data incorreta!");
                }
                //System.out.println("Fase: "+f.getChave().getFascodigo() + " - "+f.getFasdescricao());
                AtividadesPlanejadasDAO daoATAtualiza = new AtividadesPlanejadasDAO();
                daoATAtualiza.editar(at);
            }         
        }            
    }
    else{
        if (diferenca < 0){
            for (Fases f : daoFase.listar(p.getProcodigo(), 0, "", "", "", "", "")) { 

                AtividadesPlanejadasDAO daoAT = new AtividadesPlanejadasDAO();
                GregorianCalendar dtaIni = new GregorianCalendar();
                GregorianCalendar dtaFim = new GregorianCalendar();

                dtaIni.setTime(f.getFasdtainicial());
                dtaIni.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

                dtaFim.setTime(f.getFasdtafinal());
                dtaFim.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

                SimpleDateFormat formatarDate = new SimpleDateFormat("dd/MM/yyyy");   
                String DataStrIni = formatarDate.format(dtaIni.getTime());
                String DataStrFim = formatarDate.format(dtaFim.getTime());

                try {
                    f.setFasdtainicial(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrIni));
                    f.setFasdtafinal(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrFim));
                } catch (ParseException e) {
                    JOptionPane.showMessageDialog(null, "Data incorreta!");
                }
                //System.out.println("Fase: "+f.getChave().getFascodigo() + " - "+f.getFasdescricao());
                FasesDAO daoFaseAtualiza = new FasesDAO();
                daoFaseAtualiza.editar(f);

                //navega nas atividades das fases
                for (AtividadesPlanejadas at : daoAT.listar(1, f.getChave().getFascodigo(), 0, "", "", "", "", "")) { 
                    dtaIni.setTime(at.getAtiplandtainicial());
                    dtaIni.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

                    dtaFim.setTime(at.getAtiplandtafinal());
                    dtaFim.add(GregorianCalendar.DAY_OF_MONTH, diferenca);///////Aqui está adicionando a diferença

                    DataStrIni = formatarDate.format(dtaIni.getTime());
                    DataStrFim = formatarDate.format(dtaFim.getTime());

                    try {
                        at.setAtiplandtainicial(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrIni));
                        at.setAtiplandtafinal(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrFim));
                    } catch (ParseException e) {
                        JOptionPane.showMessageDialog(null, "Data incorreta!");
                    }
                    //System.out.println("Fase: "+f.getChave().getFascodigo() + " - "+f.getFasdescricao());
                    AtividadesPlanejadasDAO daoATAtualiza = new AtividadesPlanejadasDAO();
                    daoATAtualiza.editar(at);
                }         
            }
        }
    }
    
    GregorianCalendar dtaPrimeiraData = new GregorianCalendar();
    //JOptionPane.showMessageDialog(null, "DtaFinal: "+dtaFinal.getTime());
    dtaPrimeiraData.set(3000,01,01);
    
    
    //Agora altera para a data final da produção
    //FasesDAO daoFase = new FasesDAO();  
    for (Fases f : daoFase.listar(p.getProcodigo(), 0, "", "", "", "", "")) { 
        //JOptionPane.showMessageDialog(null, "Fase: "+f.getFasdescricao());
        AtividadesPlanejadasDAO daoAT = new AtividadesPlanejadasDAO();
        GregorianCalendar dta = new GregorianCalendar();
        dta.setTime(f.getFasdtafinal());
        if (dtaPrimeiraData.after(dta)== true){
            dtaPrimeiraData.setTime(dta.getTime());
        }
        //modeloFase.addRow(new String[] {""+ f.getFassequencial(), ""+ f.getFasdescricao(), "", "" + f.getFaspredecessor(), "" + f.getFasdtainicial(), ""+f.getFasdtafinal()});            
        //navega nas atividades das fases
        for (AtividadesPlanejadas at : daoAT.listar(p.getProcodigo(), f.getChave().getFascodigo(), 0, "", "", "", "", "")) { 
            //modeloFase.addRow(new String[] {""+ at.getAtiplansequencial(), "", ""+at.getAtiplandescricao(), "" + at.getAtiplanpredecessor(), ""+at.getAtiplandtainicial(), ""+at.getAtiplandtafinal(),""+at.getAtiplanintervaloantes(), ""+at.getAtiplanleadtime(),""+at.getAtiplanintervalodepois()});            
            dta.setTime(at.getAtiplandtafinal());
            if (dtaPrimeiraData.after(dta)== true){
                dtaPrimeiraData.setTime(dta.getTime());
            }
        }         
    }
    ProducaoDAO daoProd = new ProducaoDAO();
    p.setProdtainicio(dtaPrimeiraData.getTime());
    daoProd.editar(p);
    
  }
  public void calculaInicioAtividades(Producao p, int Sequencial, GregorianCalendar inicialP) throws ParseException {
    //qtde =0;
    FasesDAO daoFase = new FasesDAO();
    GregorianCalendar inicial = inicialP;
    inicial.setTime(inicialP.getTime());
    if (vetor[Sequencial]==null)
        vetor[Sequencial]=inicialP;
    //Date data = new Date(System.currentTimeMillis());
    SimpleDateFormat formatarDate = new SimpleDateFormat("dd/MM/yyyy");   
    //String DataStr = formatarDate.format(vetor[Sequencial].getTime());
    
    //Navega nas atividades 
    AtividadesPlanejadasDAO daoAT = new AtividadesPlanejadasDAO();
    //navega nas atividades das fases
    //JOptionPane.showMessageDialog(null, "Antes do for ");
    for (AtividadesPlanejadas at : daoAT.listar(p.getProcodigo(), Sequencial)) { 

        GregorianCalendar inicialAti=new GregorianCalendar();
        inicialAti.setTime(vetor[Sequencial].getTime());
        //JOptionPane.showMessageDialog(null, "inicialAti: "+inicialAti.getTime());
        if (Sequencial != 0){//pode ter intervalo antes somente quando tiver algum predecessor
            inicialAti.add(GregorianCalendar.DAY_OF_MONTH, at.getAtiplanintervaloantes());
        }
        else{
            //Zera a variável inicial quando for sequencial 0
            inicialAti.setTime(new Date());
            //JOptionPane.showMessageDialog(null, " vetor["+Sequencial+"]: "+vetor[Sequencial].getTime());
        }

        
        String DataStrInicial = formatarDate.format(inicialAti.getTime());
        try {
            at.setAtiplandtainicial(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrInicial));
        } catch (ParseException e) {
            JOptionPane.showMessageDialog(null, "Data incorreta!");
        }

        //Final = inicialP;
        GregorianCalendar Final=new GregorianCalendar();
        Final.setTime(inicialAti.getTime());
        Final.add(GregorianCalendar.DAY_OF_MONTH, at.getAtiplanleadtime());

        //JOptionPane.showMessageDialog(null, "Final: "+Final.getTime());
        String DataStrFinal = formatarDate.format(Final.getTime());
        try {
            at.setAtiplandtafinal(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrFinal));
        } catch (ParseException e) {
            JOptionPane.showMessageDialog(null, "Data incorreta!");
        }

        //inicial.settim = Final.getDate()+at.getAtiplanintervalodepois());
        inicial.setTime(Final.getTime());
        inicial.add(GregorianCalendar.DAY_OF_MONTH, at.getAtiplanintervalodepois());
        AtividadesPlanejadasDAO daoATAtualiza = new AtividadesPlanejadasDAO();
        daoATAtualiza.editar(at);
        //Chama a mesma função para pegar o predecessor
        calcula(p, at.getAtiplansequencial(), inicial);
    }   
  }
   public void calculaInicioFases(Producao p, int Sequencial, GregorianCalendar inicialP) throws ParseException {
    //qtde =0;
    FasesDAO daoFase = new FasesDAO();
    GregorianCalendar inicial = inicialP;
    inicial.setTime(inicialP.getTime());
    //if (vetor[Sequencial]==null)
        //vetor[Sequencial]=inicialP;
    //Date data = new Date(System.currentTimeMillis());
    SimpleDateFormat formatarDate = new SimpleDateFormat("dd/MM/yyyy");   
    String DataStr = formatarDate.format(vetor[Sequencial].getTime());
    
    //JOptionPane.showMessageDialog(null, "Sequencial: "+Sequencial);
    
    //SequenciaAtividades
    //Navega nas fases da produção sem predecessores para iniciar na data de hoje
    for (Fases f : daoFase.listar(p.getProcodigo(), Sequencial)) {         
        //JOptionPane.showMessageDialog(null, "Na Fase agora: "+Sequencial);
        try {
            f.setFasdtainicial(new SimpleDateFormat("dd/MM/yyyy").parse(DataStr));
        } catch (ParseException e) {
            JOptionPane.showMessageDialog(null, "Data incorreta!");
        }
        //System.out.println("Fase: "+f.getChave().getFascodigo() + " - "+f.getFasdescricao());
        FasesDAO daoFaseAtualiza = new FasesDAO();
        daoFaseAtualiza.editar(f);
        //JOptionPane.showMessageDialog(null, "Na Fase: "+Sequencial);
        calculaInicioAtividades(p, f.getFassequencial(), vetor[Sequencial]);
        
        //Pressupoem-se que as atividades dessa fase agora já estão atualizadas.
        AtividadesPlanejadasDAO daoAT = new AtividadesPlanejadasDAO();
        
        GregorianCalendar ultimaData = new GregorianCalendar();
        ultimaData.setTime(f.getFasdtainicial());
        
        for (AtividadesPlanejadas at : daoAT.listar(f.getChave().getProducao().getProcodigo(), f.getChave().getFascodigo(), 0, "", "", "", "", "")) { 
            GregorianCalendar dataAT = new GregorianCalendar();
            dataAT.setTime(at.getAtiplandtafinal());
            if (ultimaData.before(dataAT) == true){
                ultimaData.setTime(dataAT.getTime());
                //JOptionPane.showMessageDialog(null, "achou maior:"+ultimaData.getTime());
            }
        }
        
        String DataStrFinal = formatarDate.format(ultimaData.getTime());
        try {
            f.setFasdtafinal(new SimpleDateFormat("dd/MM/yyyy").parse(DataStrFinal));
        } catch (ParseException e) {
            JOptionPane.showMessageDialog(null, "Data incorreta!");
        }
        daoFaseAtualiza.editar(f);        
        calculaInicioFases(p, f.getFassequencial(), vetor[Sequencial]);
    }   
   }
    public void calcula(Producao p, int Sequencial, GregorianCalendar inicialP) throws ParseException {

        vetor[Sequencial]=inicialP;

        calculaInicioFases(p, Sequencial, vetor[Sequencial]);

        calculaInicioAtividades(p, Sequencial, vetor[Sequencial]);

  }
}